use axum::{routing::get, Router};
use rustcloud_core::{RegistryConfig, RegistryType, ServiceInstance};
use rustcloud_registry::NacosRegistry;
use std::env;
use std::sync::Arc;
use tokio::signal;
use tracing::{info, error, Level};
use tracing_subscriber::FmtSubscriber;

#[tokio::main]
async fn main() {
    // Initialize tracing
    let subscriber = FmtSubscriber::builder()
        .with_max_level(Level::INFO)
        .finish();
    tracing::subscriber::set_global_default(subscriber)
        .expect("setting default subscriber failed");

    let service_port: u16 = env::var("SERVICE_PORT")
        .expect("SERVICE_PORT env var not set")
        .parse()
        .expect("SERVICE_PORT must be a valid port number");
    let service_name = env::var("SERVICE_NAME")
        .expect("SERVICE_NAME env var not set");
    let service_host = "127.0.0.1".to_string(); // Assuming local host for simplicity

    let registry_config = RegistryConfig {
        registry_type: RegistryType::Nacos,
        server_addr: "127.0.0.1:8848".to_string(),
        namespace: None,
        group: None,
        username: None,
        password: None,
    };

    let nacos_registry = Arc::new(NacosRegistry::new(registry_config)
        .expect("Failed to create NacosRegistry"));

    let service_instance = ServiceInstance::new(
        service_name.clone(),
        service_host.clone(),
        service_port,
        "http",
    );

    // Register service to Nacos
    info!("Registering service {} to Nacos at {}:{}", service_name, service_host, service_port);
    match nacos_registry.register(service_instance.clone()).await {
        Ok(_) => info!("Service registered successfully."),
        Err(e) => {
            error!("Failed to register service: {:?}", e);
            return;
        }
    }

    // Build our application
    let app = Router::new()
        .route("/hello", get(|| async { "Hello from RustCloud service!" }));

    // Run our service
    let addr = format!("{}:{}", service_host, service_port).parse().unwrap();
    info!("Service listening on {}", addr);
    let server = axum::Server::bind(&addr)
        .serve(app.into_make_service());

    // Graceful shutdown
    let graceful_shutdown = server.with_graceful_shutdown(async {
        signal::ctrl_c().await.expect("Failed to listen for ctrl_c");
        info!("Ctrl+C received, starting graceful shutdown...");
        // Deregister service from Nacos before shutting down
        match nacos_registry.deregister(service_instance.clone()).await {
            Ok(_) => info!("Service deregistered successfully."),
            Err(e) => error!("Failed to deregister service: {:?}", e),
        }
    });

    if let Err(e) = graceful_shutdown.await {
        error!("Server error: {}", e);
    }

    info!("Service shut down.");
}